<script setup>
import { ref, onMounted, onUnmounted } from 'vue';

// WebSocket 实例
let ws = null;
let peerConnection = null;
let dataChannel = null; // 用于聊天的 DataChannel

// 用户状态
const userName = ref('');
const clientList = ref([]);
const loggedIn = ref(false);
const userKey = ref('');
const chatMessages = ref([]);

const client = ref('')

// MessageType 静态变量
const MessageType = {
  login: 0,
  signal: 1,
  text: 2,
  user: 3
};

// 连接到 WebSocket 服务端
const connectWebSocket = () => {
  ws = new WebSocket('ws://localhost:8080');

  ws.onopen = () => {
    console.log('WebSocket 连接成功');
  };

  ws.onmessage = (event) => {
    const message = JSON.parse(event.data);
    handleMessage(message);
  };

  ws.onclose = () => {
    console.log('WebSocket 连接关闭');
  };
};

// 处理接收到的消息
const handleMessage = (message) => {
  switch (message.msgtype) {
    case MessageType.text:
      console.log('收到文本消息:', message.data);
      break;
    case MessageType.user:
      clientList.value = message.data;
      console.log('更新的用户列表:', clientList.value);
      break;
    case MessageType.signal:
      handleSignalMessage(message);
      break;
    default:
      console.log('未知消息类型');
  }
};

// 处理信令消息
const handleSignalMessage = async (message) => {
  if (message.type === 'offer') {
    await handleOffer(message);
  } else if (message.type === 'answer') {
    await handleAnswer(message);
  } else if (message.type === 'candidate') {
    await handleCandidate(message);
  } else if (message.type === 'chat') {
    chatMessages.value.push({
      from: message.from,
      data: message.data
    });
    console.log(`收到来自客户端 ${message.from} 的聊天信息: ${message.data}`);
  }
};

// 创建点对点连接
const createPeerConnection = () => {
  peerConnection = new RTCPeerConnection();

  // 创建 DataChannel
  dataChannel = peerConnection.createDataChannel('chat');
  dataChannel.onopen = () => {
    console.log('DataChannel 已打开');
  };
  dataChannel.onmessage = (event) => {
    chatMessages.value.push({
      from: '对方',
      data: event.data
    });
    console.log(`收到消息: ${event.data}`);
  };

  // ICE 处理
  peerConnection.onicecandidate = (event) => {
    // todo 第一次连接，这里发送了五次
    console.log("ICE 处理");
    
    if (event.candidate) {
      ws.send(JSON.stringify({
        msgtype: MessageType.signal,
        client: 'all',
        type: 'candidate',
        data: event.candidate
      }));
    }
  };

  peerConnection.ondatachannel = (event) => {
    event.channel.onmessage = (event) => {
      chatMessages.value.push({
        from: '对方',
        data: event.data
      });
      console.log(`收到消息: ${event.data}`);
    };
  };
};

// 发送聊天信息
const sendChatMessage = (message) => {
  if (dataChannel && dataChannel.readyState === 'open') {
    dataChannel.send(message);
    chatMessages.value.push({
      from: '自己',
      data: message
    });
  } else {
    console.error('DataChannel 未打开或不可用');
  }
};

// 发送offer
const sendOffer = async ()=>{
    if (!peerConnection) {
    createPeerConnection();
  }
  console.log("发送offer");
  
    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);
    ws.send(JSON.stringify({
    msgtype: MessageType.signal,
    client: 'all',
    type: 'offer',
    data: offer
  }));
}

// 处理 offer
const handleOffer = async (message) => {
  if (!peerConnection) {
    createPeerConnection();
  }
  console.log(message)
  await peerConnection.setRemoteDescription(new RTCSessionDescription(message.data));

  const answer = await peerConnection.createAnswer();
  await peerConnection.setLocalDescription(answer);

  ws.send(JSON.stringify({
    msgtype: MessageType.signal,
    client: message.cl,
    type: 'answer',
    data: answer
  }));
};

// 处理 answer
const handleAnswer = async (message) => {
  await peerConnection.setRemoteDescription(new RTCSessionDescription(message.data));
};

// 处理 ICE candidate
const handleCandidate = async (message) => {
  try {
    await peerConnection.addIceCandidate(new RTCIceCandidate(message.data));
  } catch (e) {
    console.error('添加 ICE Candidate 时出错:', e);
  }
};

// 登录
const login = () => {
  if (!userName.value) {
    alert('请输入用户名');
    return;
  }

  const loginMessage = {
    msgtype: MessageType.login,
    name: userName.value
  };
  ws.send(JSON.stringify(loginMessage));
  loggedIn.value = true;
  userKey.value = generateKey(userName.value);
};

// 生成客户端密钥（与服务端一致）
const generateKey = (name) => {
  return btoa(unescape(encodeURIComponent(name + '8080'))); // 假设端口号为8080
};

// 在组件挂载时连接 WebSocket
onMounted(() => {
  connectWebSocket();
});

// 在组件卸载时关闭 WebSocket 连接
onUnmounted(() => {
  if (ws) {
    ws.close();
  }
});
</script>

<template>
  <div>
    <input v-model="userName" placeholder="输入用户名" />
    <button @click="login">登录</button>
    <button @click="sendChatMessage(userName)">发送聊天信息</button>
    <button @click="sendOffer">发送offer</button>
    <div v-if="loggedIn">
      <h3>在线用户列表:</h3>
      <ul>
        <li v-for="client in clientList" :key="client.key">{{ client.name }}</li>
      </ul>

      <h3>聊天信息:</h3>
      <ul>
        <li v-for="(msg, index) in chatMessages" :key="index">
          {{ msg.from }}: {{ msg.data }}
        </li>
      </ul>
    </div>
  </div>
</template>
